/**
 * All Rights Reserved , Copyright (C) 2020 , 青岛鼎信通讯股份有限公司
 * <p>
 * PmProjectService 项目基本信息
 * <p>
 * 修改纪录 2020-05-18 版本：1.0 liwanpeng 创建。
 *
 * @version 版本：1.0
 * @author 作者：liwanpeng 创建日期：2020-05-18
 */
package com.topscomm.pm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.pm.PmSystemConst;
import com.topscomm.pm.pojo.PmBudgetLineEntity;
import com.topscomm.pm.pojo.PmProjectEntity;
import com.topscomm.pm.service.IPmBudgetLineService;
import com.topscomm.pm.service.IPmProjectService;
import com.topscomm.pm.service.impl.auto.PmProjectServiceAuto;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.ParameterCache;
import com.topscomm.tap.common.SessionUserBean;

import java.util.*;

import com.topscomm.tap.security.SecurityUserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

@Service(value = "pmProjectService")
@Scope(value = "singleton")
public class PmProjectService extends PmProjectServiceAuto implements IPmProjectService {

    @Autowired
    private IPmBudgetLineService pmBudgetLineService;
    @Autowired
    @Qualifier("securityUserDetailsService")
    private UserDetailsService userDetailsService;

    /**
     * @param entity
     * @throws ServiceException
     * @author: liwanpeng
     * @date: 2020-05-18
     * @description:单号生成
     * @modify:
     */
    @Override
    protected void beforeInsert(BasicEntity entity) {
        super.beforeInsert(entity);
        if (entity.getId() <= 0) {// 赋值Id和单号
            long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
            entity.setId(arrayId[0]);
            String docNo = String.valueOf(arrayId[0]);
            //项目code
            docNo = docNo.substring(0, 6) + docNo.substring(9);
            entity.setValue(PmProjectEntity.FieldDocno, docNo);
//            entity.setValue(PmProjectEntity.FieldCode, "P" + docNo);
            entity.setValue(PmProjectEntity.FieldProjectstate, 0);
        }

    }

    /**
     * @param entity
     * @throws ServiceException
     * @author: liwanpeng
     * @date: 2020-06-12
     * @description:插入项目信息后添加预算信息
     * @modify:
     */
    @Override
    protected void afterInsert(BasicEntity entity) {
        super.beforeInsert(entity);
        if (entity.getId() > 0) {// 赋值Id和单号
            //项目id
            long projectId = entity.getId();
            // 预算信息
            Map<String, Object> budgetInfoMap = entity.getDataCache();
            JSONArray listBudget = JSON
                .parseArray(JSON.toJSONString(budgetInfoMap.get("budgetDetails")));
            List<BasicEntity> listBasicEntity = new ArrayList<>();
            for (int i = 0; i < listBudget.size(); i++) {
                JSONObject pmBudgetLineEntity = listBudget.getJSONObject(i);
                pmBudgetLineEntity.put("projectid", projectId);
                pmBudgetLineEntity.put("state", 9);//默认已通过审核
                pmBudgetLineEntity.put("adddate", new Date());
                listBasicEntity.add(pmBudgetLineEntity.toJavaObject(PmBudgetLineEntity.class));
            }

            pmBudgetLineService.insertBatch(listBasicEntity);
            //=========================沿用旧系统规则生成项目号,去除前两位省份编码，日期八位，流水号三位，默认每天系统立项不会超过1000个项目=========================
            // modify by wushenghong  项目编号 GC + 8位日期 + 三位流水
            PmProjectEntity pmProjectEntity = this
                .queryById(ConvertUtil.convertToString(projectId));
            if (pmProjectEntity != null) {
                String projectCode = "";
                String formatDate = cn.hutool.core.date.DateUtil.format(new Date(), "yyyyMMdd");
                String startCode = "GC" + formatDate;
                StringBufferProxy sql = new StringBufferProxy();
                sql.appendSingle("SELECT MAX(CODE) code FROM PMPROJECT WHERE CODE LIKE '{0}%' ",
                    startCode);
                List<Map<String, Object>> codeList = this.selectExecute(sql.toString());
                if (codeList.size() > 0) {
                    projectCode = codeList.get(0).get("code").toString();
                    int endCode = Integer.parseInt(projectCode.substring(10, 13)) + 1;
                    projectCode = startCode + String.format("%03d", endCode);
                } else {
                    projectCode = startCode + "000";
                }
                pmProjectEntity.setCode(projectCode);
                this.updateEntity(pmProjectEntity);
            }
        }
    }

    /**
     * @param map
     * @throws ServiceException
     * @author: liwanpeng
     * @date: 2020-06-12
     * @description:插入项目信息后添加预算信息
     * @modify:
     */
    @Override
    protected void updateAfter(Map<String, Object> map) {
        super.updateAfter(map);
        //项目id
        long projectId = ConvertUtil.convertToLong(map.get("id"));
        JSONArray listBudget = JSON.parseArray(JSON.toJSONString(map.get("budgetDetails")));

        if (listBudget != null && listBudget.size() > 0) {
            // 删除原有详细预算
            StringBufferProxy deleteSql = new StringBufferProxy();
            deleteSql.appendSingle("projectid = {0} and budgetapplyid >= 0", projectId);
            pmBudgetLineService.deleteByWhere(deleteSql.toString());
            // 预算信息
            List<BasicEntity> listBasicEntity = new ArrayList<>();
            for (int i = 0; i < listBudget.size(); i++) {
                JSONObject pmBudgetLineEntity = listBudget.getJSONObject(i);
                pmBudgetLineEntity.put("projectid", projectId);
                pmBudgetLineEntity.put("state", 9); //默认已通过审核
                pmBudgetLineEntity.put("adddate", new Date());
                listBasicEntity.add(pmBudgetLineEntity.toJavaObject(PmBudgetLineEntity.class));
            }

            pmBudgetLineService.insertBatch(listBasicEntity);
        }

    }

    @Override
    protected void afterSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
        //项目id
        long projectId = ConvertUtil.convertToLong(entity.getId());
        JSONArray listBudget = JSON
            .parseArray(JSON.toJSONString(entity.getDataCache().get("budgetDetails")));

        if (listBudget != null && listBudget.size() > 0) {
            // 删除原有详细预算
            StringBufferProxy deleteSql = new StringBufferProxy();
            deleteSql.appendSingle("projectid = {0} and budgetapplyid >= 0", projectId);
            pmBudgetLineService.deleteByWhere(deleteSql.toString());
            // 预算信息
            List<BasicEntity> listBasicEntity = new ArrayList<>();
            for (int i = 0; i < listBudget.size(); i++) {
                JSONObject pmBudgetLineEntity = listBudget.getJSONObject(i);
                pmBudgetLineEntity.put("projectid", projectId);
                pmBudgetLineEntity.put("state", 9);
                pmBudgetLineEntity.put("adddate", new Date());
                listBasicEntity.add(pmBudgetLineEntity.toJavaObject(PmBudgetLineEntity.class));
            }

            pmBudgetLineService.insertBatch(listBasicEntity);
        }
        super.afterSubmit(entity, sessionUserBean);
    }


    // 通过省区部门编码获取对应的省区值集
    @Transactional
    public String getAreaInfoFromCrm(String deptcode,String deptname) throws Exception {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(2000);// 设置超时
        requestFactory.setReadTimeout(100000);// 读取超时时间
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        String token = ParameterCache.getValue(PmSystemConst.GetInfoFromCrmToken);
        String templateid = ParameterCache.getValue(PmSystemConst.GetInfoFromCrmTemplateId);
        headers.set("token", token);
        JSONObject map = new JSONObject();
        map.put("templateid", templateid);
        try{
            String url = ParameterCache.getValue(PmSystemConst.GetInfoFromCrmUrl);
            JSONObject params = new JSONObject();
            String querycode="";
            String AreaPublic=ParameterCache.getValue(PmSystemConst.AreaPublic);
            // 四川分公司、重庆分公司、股份北京分公司 的部门编号有'_'，目前分公司的区域的部门编号 到'_'后六位，今后有可能区域下又划
            // 分了更小的部门（不可以直接把获取到的deptcode直接传到crm），所以有'_'的并且'_'后的编号长度为6位，截取到'_'后六位   因为一级部门下还有行
            // 销部等非区域的部门，类似行销部(行销部的编号长度也到下划线的后六位)的需要划归到省区公共(比如 鼎信股份\股份山东\行销部划分到省区公共)，
            // 所以向CRM传值时，如果当前部门编号是区域的编号，传区域部门编号和所在一级部门编号，如果当前部门编号不是区域的编号，则只传当前编号即可（例如可以得到 山东公共）
            if(deptcode.contains("_")){
                String substring = deptcode.substring(deptcode.indexOf('_')+1);
                if(substring.length()>=6){
                    querycode=deptcode.substring(0,deptcode.indexOf('_')+7);
                } else if(substring.length()==4){
                    querycode=deptcode.substring(0,deptcode.indexOf('_')+5);
                }
            }else{
                //今后有可能区域下又划分了更小的部门（所以不可以直接把获取到的deptcode直接传到crm）,逻辑和上面一样，如果当前部门
                // 编号是区域的编号，传区域部门编号和所在一级部门编号，如果当前部门编号不是区域的编号，则只传当前编号即可（例如可以得到 山东公共）
                if(deptcode.length()>=6){
                    querycode=deptcode.substring(0,6);
                }else{
                    querycode=deptcode;
                }
            }
//            if("".equals(yiJiDeptCode)){
//                params.put("code", "'"+querycode+"'");
//            }else{
//                String t="'"+querycode+"','"+yiJiDeptCode+"'";
//                params.put("code", t);
//            }
            String t="'"+querycode+"','"+AreaPublic+"'";
            params.put("code",t);
            map.put("paramsMap", params);
            HttpEntity<JSONObject> request = new HttpEntity<>(map, headers);
            ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
            if(response.getBody().getBooleanValue("success")==true){
                List<Map<String, Object>> dataList = (List<Map<String, Object>>) response.getBody().getJSONObject("result").get("dataList");
                String areacode="";
                if(dataList.size()>1){
                    for(int i=0;i<dataList.size();i++){
                        if(deptcode.equals(dataList.get(i).get("code"))){
                            areacode=ConvertUtil.convertToString(dataList.get(i).get("Name"));
                            break;
                        }
                    }
                }else{
                    if(deptname.contains("区域")){
                        throw new Exception("该区域未维护销售区域编码配置，请联系管理员！");
                    }
                    areacode=ConvertUtil.convertToString(dataList.get(0).get("Name"));
                }
                return areacode;
            }else{
                throw new Exception(response.getBody().getString("message"));
            }
        }catch (Exception e){
            throw new Exception(e.getMessage());
        }
    }



    // 通过省区部门编码获取对应的省区值集（项目报表、收据开具查询模块调用）
    @Transactional
    public String getAreaInfoFromCrmForquery(String deptcode) throws Exception {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(2000);// 设置超时
        requestFactory.setReadTimeout(100000);// 读取超时时间
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        String token = ParameterCache.getValue(PmSystemConst.GetInfoFromCrmToken);
        String templateid = ParameterCache.getValue(PmSystemConst.GetInfoFromCrmTemplateId);
        headers.set("token", token);
        JSONObject map = new JSONObject();
        map.put("templateid", templateid);
        try{
            String url = ParameterCache.getValue(PmSystemConst.GetInfoFromCrmUrl);
            JSONObject params = new JSONObject();
            String querycode="";
            // 四川分公司、重庆分公司、股份北京分公司 的部门编号有'_'，目前分公司的区域的部门编号 到'_'后六位，今后有可能区域下又划
            // 分了更小的部门（不可以直接把获取到的deptcode直接传到crm），所以有'_'的并且'_'后的编号长度为6位，截取到'_'后六位
            if(deptcode.contains("_")){
                String substring = deptcode.substring(deptcode.indexOf('_')+1);
                if(substring.length()>=6){
                    querycode=deptcode.substring(0,deptcode.indexOf('_')+7);
                } else if(substring.length()==4){
                    querycode=deptcode.substring(0,deptcode.indexOf('_')+5);
                } else {
                    querycode=deptcode;
                }
            }else{
                //今后有可能区域下又划分了更小的部门（所以不可以直接把获取到的deptcode直接传到crm）
                if(deptcode.length()>=6){
                    querycode=deptcode.substring(0,6);
                }else if(deptcode.length()==4){
                    querycode=deptcode.substring(0,4);
                }else{
                    // 有的历史数据所属部门是公司的(例如D1)
                    querycode=deptcode;
                }
            }
            params.put("code", "'"+querycode+"'");
            map.put("paramsMap", params);
            HttpEntity<JSONObject> request = new HttpEntity<>(map, headers);
            ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
            if(response.getBody().getBooleanValue("success")==true){
                List<Map<String, Object>> dataList = (List<Map<String, Object>>) response.getBody().getJSONObject("result").get("dataList");
                String areacode="";
                if(dataList.size()>0){
                    areacode=ConvertUtil.convertToString(dataList.get(0).get("Name"));
                }
                return areacode;
            }else{
                throw new Exception(response.getBody().getString("message"));
            }
        }catch (Exception e){
            throw new Exception(e.getMessage());
        }
    }

    /**
     * @author: duzehou
     * @date: 2017年3月6日下午4:35:17
     * @params: @param whereSql
     * @params: @param curPageIndex
     * @params: @param pageSize
     * @params: @param sidx
     * @params: @param sord
     * @params: @return
     * @description: FDS取数分页查询
     * @modify:
     */
    public List<Map<String, Object>> queryMapForPageFds(String whereSql, int curPageIndex, int pageSize, String sidx,
                                                        String sord) {
        int beginCount = curPageIndex * pageSize - pageSize;
        Map<String, Object> paraMap = new HashMap<String, Object>();
        paraMap.put("begincount", beginCount);
        paraMap.put("pagesize", pageSize);
        paraMap.put("whereSql", whereSql);
        paraMap.put("sidx", sidx);
        paraMap.put("sord", sord);
        return queryMapForPageFds(paraMap);
    }
    public List<Map<String, Object>> queryMapForPageFds(Map<String, Object> paraMap) {
        List<Map<String, Object>> listResultMap = dao.queryMapForPage(paraMap, "queryMapForPageFds");
        setDispFieldsFds(listResultMap);
        return listResultMap;
    }

    /**
     * @description:  FDS金额取数不分页查询
     * @author: duzehou
     * @date: 2022/12/21 15:48
     * @param: [whereSql]
     * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    @Override
    public List<Map<String, Object>> queryMapByWhereFdsFund(String whereSql) {
        List<Map<String, Object>> listResultMap = dao.queryMapByWhere(whereSql,"queryMapByWhereFdsFund");
        setDispFieldsFds(listResultMap);
        return listResultMap;
    }
    public void setDispFieldsFds(List<Map<String, Object>> mapRowList) {
//        DatacodeCache datacodeCache = (DatacodeCache) SpringUtil.getBean("datacodeCache");
        for (Map<String, Object> mapRow : mapRowList) {
            mapRow.put("category","9");
//            setDispFields(mapRow, datacodeCache);
        }
    }
    /**
     * @description: 根据用户code获取sessionuserbean信息
     * @author: houyuhang
     * @date: 2023年01月04日
     * @modify:
     */
    public SessionUserBean querySessionUserBean(String usercode) {
        SecurityUserDetails userDetails = (SecurityUserDetails) userDetailsService.loadUserByUsername(usercode);
        SessionUserBean sessionUserBean = new SessionUserBean();
        sessionUserBean.setUser(userDetails.getUser());
        sessionUserBean.setOrg(userDetails.getOrg());
        sessionUserBean.setWorkOrg(userDetails.getWorkOrg());
        sessionUserBean.setDept(userDetails.getDept());
        sessionUserBean.setWorkDept(userDetails.getWorkDept());
        sessionUserBean.setRoleList(userDetails.getRoleList());
        return sessionUserBean;
    }
}
